From: Joshua Goins Date: Mon, 30 Jun 2025 23:38:05 +0000 (-0400) Subject: [PATCH] Playback audio in video attachments X-Git-Tag: archive/raspbian/25.04.3-1+rpi1^2~5 X-Git-Url: https://dgit.raspbian.org/%22http:/www.example.com/cgi/%22https:/%22bookmarks:///%22http:/www.example.com/cgi/%22https:/%22bookmarks:/?a=commitdiff_plain;h=8a0b557aba32a6aabc821a9b619afff300e6571a;p=tokodon.git [PATCH] Playback audio in video attachments When porting to QtMultimedia fully, I forgot that we needed to manually add a VideoOutput too. CCBUG: 505303 TODO: * Fix the volume control hiding when it shouldn't, and test on mobile Gbp-Pq: Name upstream_fc886374_Playback-audio-in-video-attachments.patch --- diff --git a/src/content/ui/Components/VideoPlayer.qml b/src/content/ui/Components/VideoPlayer.qml index f5e2a6a..c8dc704 100644 --- a/src/content/ui/Components/VideoPlayer.qml +++ b/src/content/ui/Components/VideoPlayer.qml @@ -17,6 +17,7 @@ Item { property alias source: player.source property alias position: player.position property bool looping + property alias volume: audioOutput.volume signal errorOccurred(error: int, errorString: string) @@ -35,6 +36,9 @@ Item { MediaPlayer { id: player videoOutput: videoOutput + audioOutput: AudioOutput { + id: audioOutput + } loops: root.looping ? MediaPlayer.Infinite : 0 onMediaStatusChanged: { diff --git a/src/content/ui/PostDelegate/VideoAttachment.qml b/src/content/ui/PostDelegate/VideoAttachment.qml index 91f7804..58a1993 100644 --- a/src/content/ui/PostDelegate/VideoAttachment.qml +++ b/src/content/ui/PostDelegate/VideoAttachment.qml @@ -21,6 +21,7 @@ MediaContainer { property alias showControls: mediaControls.visible property bool looping: false property alias loading: busyIndicator.visible + property real volume: 1.0 signal errorOccurred(error: int, errorString: string) @@ -56,6 +57,7 @@ MediaContainer { source: root.videoUrl looping: root.looping onErrorOccurred: (error, errorString) => root.errorOccurred(error, errorString) + volume: root.volume } } @@ -78,6 +80,13 @@ MediaContainer { HoverHandler { id: hoverHandler + + acceptedDevices: PointerDevice.Mouse | PointerDevice.TouchPad + onHoveredChanged: { + if (hovered) { + mediaControlsHideTimer.restart(); + } + } } QQC2.BusyIndicator { @@ -132,13 +141,18 @@ MediaContainer { radius: Kirigami.Units.cornerRadius color: Kirigami.Theme.backgroundColor - opacity: hoverHandler.hovered && !root.isSensitive && !(player.item?.paused ?? true) && !(player.item?.stopped ?? true) ? 0.7 : 0.0 + opacity: (mediaControlsHideTimer.running || volumePopupTimer || hoverHandler.hovered) && !root.isSensitive && !(player.item?.paused ?? true) && !(player.item?.stopped ?? true) ? 0.7 : 0.0 Behavior on opacity { OpacityAnimator { duration: Kirigami.Units.longDuration } } + Timer { + id: mediaControlsHideTimer + interval: 5000 + } + RowLayout { id: mediaControlsLayout anchors.fill: parent @@ -173,6 +187,80 @@ MediaContainer { onMoved: player.item?.setPosition(value) } + + QQC2.ToolButton { + id: volumeButton + + property var unmuteVolume: root.volume + + icon.name: root.volume <= 0 ? "player-volume-muted-symbolic" : "player-volume-symbolic" + + QQC2.ToolTip.visible: hovered + QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay + QQC2.ToolTip.timeout: Kirigami.Units.toolTipDelay + QQC2.ToolTip.text: i18nc("@action:button", "Volume") + + onClicked: { + if (root.volume > 0) { + root.volume = 0; + } else if (unmuteVolume === 0) { + root.volume = 1; + } else { + root.volume = unmuteVolume; + } + } + + QQC2.Popup { + id: volumePopup + y: -height + width: volumeButton.width + visible: (volumeButton.hovered || volumePopupHoverHandler.hovered || volumeSlider.hovered || volumePopupTimer.running) + + focus: true + padding: Kirigami.Units.smallSpacing + closePolicy: QQC2.Popup.NoAutoClose + + QQC2.Slider { + id: volumeSlider + anchors.centerIn: parent + implicitHeight: Kirigami.Units.gridUnit * 7 + orientation: Qt.Vertical + padding: 0 + from: 0 + to: 1 + value: root.volume + onMoved: { + root.volume = value; + volumeButton.unmuteVolume = value; + } + } + Timer { + id: volumePopupTimer + interval: 1000 + } + HoverHandler { + id: volumePopupHoverHandler + + onHoveredChanged: { + if (hovered) { + volumePopupTimer.restart(); + } + } + } + background: Kirigami.ShadowedRectangle { + radius: Kirigami.Units.cornerRadius + color: Kirigami.Theme.backgroundColor + opacity: 0.8 + + shadow { + xOffset: 0 + yOffset: 4 + color: Qt.rgba(0, 0, 0, 0.3) + size: Kirigami.Units.largeSpacing + } + } + } + } } } }